const express = require('express')
// const WechatPay = require('wechatpay-nodejs-sdk')
const WechatPay = require('../wechatpay-nodejs-sdk')
const router = express.Router()
const Order = require('../models/Order')
const Product = require('../models/Product')
const logger = require('../logger')
const { ORDER_STATUS } = require('../constants')
const fs = require('fs')
const { WECHAT_APP_ID, WECHAT_MCH_ID, WECHAT_NOTIFY_URL, SECRET_KEY } = require('../config')
const wechatpay = new WechatPay({
  appid: WECHAT_APP_ID, // 服务ID
  mchid: WECHAT_MCH_ID, // 商户ID
  secretKey: SECRET_KEY, // V3密钥
  publicKey: fs.readFileSync('./apiclient_cert.pem'), // 商户的公钥
  privateKey: fs.readFileSync('./apiclient_key.pem') // 商户的私钥
})
async function createOrder(productId) {
  // 1.检查订单的ID是否正确
  const product = await Product.findById(productId)
  if (!product) {
    throw new Error('产品未找到')
  }
  const newOrder = new Order({
    product: productId,
    totalFee: product.price,
    orderStatus: ORDER_STATUS.UN_PAID
  })
  await newOrder.save()
  return { product, newOrder }
}
async function invokeWechatPay(order, product, req) {
  const result = await wechatpay.transactions_native({
    description: `购买${product.name}`, // 交易的描述
    out_trade_no: order.id, // 商户的订单号
    notify_url: `${WECHAT_NOTIFY_URL}`,
    amount: { // 订单金额
      total: product.price, // 总金额
      currency: 'CNY'
    },
    scene_info: { // 场景信息
      payer_client_ip: req.ip // 用户终端IP
    }
  })
  logger.info(`transactions_native.result: ${JSON.stringify(result)}`)
  const { code_url } = result
  // 更新订单信息，把支付二维码地址保存到订单里
  await Order.findByIdAndUpdate(order.id, { code_url })
  return code_url
}
router.get(`/native/:productId`, async function (req, res) {
  try {
    // 1. 生成订单
    const { productId } = req.params
    const { product, newOrder } = await createOrder(productId)
    // 2. 调用统一下单接口API
    const code_url = await invokeWechatPay(newOrder, product, req)
    // 3. 把新生成的订单号和支付二维码地址发回给客户端
    res.send({ orderNo: newOrder.id, code_url})
  } catch (error) {
    logger.error(`Native Pay Error`, error)
    res.status(500).send(error.message)
  }
})
router.get('/callback', (req, res) => {
  res.status(200).send({
    code: 'SUCCESS',
    message: 'Payment successfully'
  })
})
/**
 * 接收微信服务器发给商户后台的支付成功的通知
 */
router.post('/callback', async (req, res) => {
  try {
    // 步骤一：验证签名 保证此通知真的是由微信服务器发过来的
    const { headers, body } = req
    logger.info('headers:::::::', JSON.stringify(headers))
    // Wechatpay-Signature 签名
    const signature = headers['wechatpay-signature']
    logger.info('signature111', signature)
    // Wechatpay-Serial 微信服务器平台的证书序列号
    const serial = headers['wechatpay-serial']
    logger.info('serial', serial)
    // HTTP 头 Wechatpay-Timestamp 中的应答时间戳
    const timestamp = headers['wechatpay-timestamp']
    logger.info('timestamp', timestamp)
    // HTTP 头 Wechatpay-Nonce 中的应答随机串
    const nonce = headers['wechatpay-nonce']
    // 应答报文主体（Response Body），请使用原始报文主体执行验签
    logger.info('nonce', nonce)
// 应答时间戳\n
// 应答随机串\n
// 应答报文主体\n

    const isVerified = await wechatpay.verifySign({
      body, // 请求主题
      signature, // 微信服务器发过来的签名
      nonce, // 随机字符串
      timestamp, // 时间戳
      serial // 证书序列号
    })
    logger.info('isVerified', isVerified)
    // 如果事件类型是TRANSACTION.SUCCESS说明交易成功，说明用户支付成功
    if (isVerified && body && body.event_type === 'TRANSACTION.SUCCESS') {
      const resultStr = wechatpay.decrypt(body.resource)
      const result = JSON.parse(resultStr)
      logger.info('TRANSACTION.SUCCESS', result)
      // 更新订单的状态为支付成功
      await Order.findByIdAndUpdate(result.out_trade_no, {
        orderStatus: ORDER_STATUS.PAID
      })
      res.status(200).send({
        code: 'SUCCESS',
        message: '支付成功'
      })
    } else {
      res.status(200).send({
        code: 'FAIL',
        message: '支付失败'
      })
    }
  } catch (error) {
    logger.error('接收通知失败', error)
    res.status(500).send(`处理微信支付服务器回调失败` + error.message)
  }
})
router.get(`/order/:orderNo`, async (req, res) => {
  try {
    const { orderNo } = req.params
    const result = await wechatpay.query(orderNo)
    logger.info('query order', result)
    res.status(200).send(result)
  } catch (error) {
    logger.error('查询交易状态失败', error)
    res.status(500).send(`查询交易状态失败`, + error.message)
  }
})
router.get(`/order/:orderNo/close`, async (req, res) => {
  try {
    const { orderNo } = req.params
    await wechatpay.close(orderNo)
    await Order.findByIdAndUpdate(orderNo, { orderStatus: ORDER_STATUS.CLOSE })
    res.status(200).send({ message: '关闭订单成功' })
  } catch (error) {
    logger.error('关闭订单失败', error)
    res.status(500).send(`关闭订单失败`, + error.message)
  }
})
module.exports = router
